#ifndef CELL_HPP
#define CELL_HPP

#include <NTL/vec_GF2.h>
#include <vector>
NTL_CLIENT


// the domain of PCM Cells
struct Cell {
  double R;        // current log-resistance
  double R0;       // initial log-resistance
  int L;           // current cell level according to R and thresholds
  int L0;          // initial cell level according to R0  and thresholds
  vec_GF2* bits;   // current bits according to L
  vec_GF2* bits0;  // initial bits according to L0
  long t;          // cell life time  
  double V;        // drift exponent
  explicit Cell(double& r0, int& l, 
		double& v, vec_GF2* bts): 
    R(r0), R0(r0),  L(l), L0(l), t(0), V(v) {
    bits = bts;
    bits0 = new vec_GF2(*bits);
  }
};

inline ostream& operator<< (ostream& out, Cell& cell)
{
  out << "Cell["; 
  out << " R=" << cell.R;
  out << " R0=" << cell.R0;
  out << " L=" << cell.L;
  out << " L0=" << cell.L0;
  out << " bits=" << *(cell.bits);
  out << " bits0=" << *(cell.bits0);
  out << " t=" << cell.t;
  out << " V=" << cell.V;
  out << "]";;
  return out;
}

// functor for comparing a pair
struct ltpair {
  bool operator()(const pair<GF2, long> p1, const pair<GF2, long> p2) const
  {
    return (p1.second <  p2.second);
  }
};

typedef vector< Cell* > Cells;


namespace CellUtil{
  void read_bits_from_cell(vec_GF2& bits, const Cells& cells);
  // compute the levels of the cells according to the codeword
  void compute_cell_levels(vector<int>& levels, const vec_GF2& codeword);
  // compute bit error rate given the PCM cells.
  double compute_bit_error_rate(const vector< Cell* >& cells, const long& n);

}

#endif // CELL_HPP
